import React, { memo, useState, useRef, useEffect } from 'react'
import type { FC, ReactNode } from 'react'
import { NavLink } from 'react-router-dom'
import { BarControl, BarOperator, BarPlayInfo, PlayerBarWrapper } from './style'
import { Slider, message } from 'antd'
import { useAppDispatch, useAppSelect } from '@/store'
import { getImageSize } from '@/utils/format'
import { shallowEqual } from 'react-redux'
import { formatTime, getPlayerUrl } from '@/utils/handle-player'
import {
  changeLyricIndexAction,
  changeMusicAction,
  changePlayModeAction
} from '../store/player'

interface IProps {
  children?: ReactNode
}
const AppPlayerBar: FC<IProps> = () => {
  const [isPlaying, setIsPlaying] = useState(false)
  const [progress, setProgress] = useState(0)
  const [duration, setDuration] = useState(0)
  const [currentTime, setCurrentTime] = useState(0)
  const [isSliding, setIsSliding] = useState(false)
  const audioRef = useRef<HTMLAudioElement>(null)
  const { currentSong, lyrics, lyricIndex, playMode } = useAppSelect(
    (state) => ({
      currentSong: state.player.currentSong,
      lyrics: state.player.lyrics,
      lyricIndex: state.player.lyricIndex,
      playMode: state.player.playMode
    }),
    shallowEqual
  )
  const dispatch = useAppDispatch()
  /* 组件内副作用操作 */
  useEffect(() => {
    setDuration(currentSong?.dt)
    audioRef.current!.src = getPlayerUrl(currentSong?.id)
    /* 一进来自动播放 */
    audioRef.current
      ?.play()
      .then(() => {
        console.log('播放成功')
        setIsPlaying(true)
      })
      .catch((error) => {
        setIsPlaying(false)
      })
  }, [currentSong])

  function handlePlayClick() {
    setIsPlaying(!isPlaying)

    !isPlaying
      ? audioRef.current?.play().catch(() => setIsPlaying(false))
      : audioRef.current?.pause()
  }
  function handleChangeMusic(isNext = true) {
    dispatch(changeMusicAction(isNext))
  }
  function handleTimeUpdate() {
    isPlaying && setIsPlaying(true)
    console.log(isPlaying, 2)
    /* 判断是否在拖拽 */
    const currentTime = audioRef.current!.currentTime * 1000
    /* 拖拽的时候不设置进度条 */
    if (!isSliding) {
      const progress = (currentTime / duration) * 100
      setProgress(progress)
      setCurrentTime(currentTime)
    }
    /* 歌词匹配 */
    /* 给index默认匹配最后一个，当当前时间比最后一句歌词时间大时不会再对index赋值 */
    let index = lyrics.length - 1
    for (let i = 0; i < lyrics.length; i++) {
      const lyric = lyrics[i]
      /* 一旦发现当前时间比歌词时间打，立马拿到当前歌词的上一个时间段歌词 */
      if (lyric.time > currentTime) {
        index = i - 1
        break
      }
    }
    /* 匹配对应歌词的index,防止歌词一直被展示 */
    if (lyricIndex === index || index === -1) return
    dispatch(changeLyricIndexAction(index))
    message.open({
      content: lyrics[index].text,
      duration: 0,
      key: 'lyric'
    })
  }
  function handleTimeEnded() {
    if (playMode == 2) {
      audioRef.current!.currentTime = 0
      audioRef.current?.play()
    } else {
      handleChangeMusic(true)
    }
  }
  function handleAfterChange(value: number) {
    const currentTime = (value / 100) * duration
    audioRef.current!.currentTime = currentTime / 1000
    setCurrentTime(currentTime)
    setProgress(value)
    setIsSliding(false)
  }
  function handleSliderChanging(value: number) {
    /* 设置进度条 */
    setProgress(value)
    /* 设置拖拽状态 */
    setIsSliding(true)
    /* 拖拽变化时间 */
    const currentTime = (value / 100) * duration
    setCurrentTime(currentTime)
  }
  function handleChangePlayMode() {
    let newPlayMode = playMode + 1
    if (newPlayMode > 2) {
      newPlayMode = 0
    }
    dispatch(changePlayModeAction(newPlayMode))
  }
  return (
    <PlayerBarWrapper className="sprite_playbar">
      <div className="content wrap-v2">
        <BarControl isPlaying={isPlaying}>
          <button
            className="btn sprite_playbar prev"
            onClick={() => handleChangeMusic(false)}
          ></button>
          <button
            className="btn sprite_playbar play"
            onClick={handlePlayClick}
          ></button>
          <button
            className="btn sprite_playbar next"
            onClick={() => handleChangeMusic(true)}
          ></button>
        </BarControl>
        <BarPlayInfo>
          <NavLink to="/discover/player">
            <img
              className="image"
              src={getImageSize(currentSong?.al?.picUrl, 50)}
              alt=""
            />
          </NavLink>
          <div className="info">
            <div className="song">
              <span className="song-name">{currentSong?.name}</span>
              <span className="singer-name">{currentSong?.ar?.[0]?.name}</span>
            </div>
            <div className="progress">
              <Slider
                value={progress}
                step={0.5}
                tooltip={{ formatter: null }}
                onAfterChange={handleAfterChange}
                onChange={handleSliderChanging}
              ></Slider>
              <div className="time">
                <span className="current">{formatTime(currentTime)}</span>
                <span className="divider">/</span>
                <span className="duration">{formatTime(duration)}</span>
              </div>
            </div>
          </div>
        </BarPlayInfo>
        <BarOperator playMode={playMode}>
          <div className="left">
            <button className="btn pip"></button>
            <button className="btn sprite_playbar favor"></button>
            <button className="btn sprite_playbar share"></button>
          </div>
          <div className="right sprite_playbar">
            <button className="btn sprite_playbar volume"></button>
            <button
              className="btn sprite_playbar loop"
              onClick={handleChangePlayMode}
            ></button>
            <button className="btn sprite_playbar playlist"></button>
          </div>
        </BarOperator>
      </div>
      <audio
        ref={audioRef}
        onTimeUpdate={handleTimeUpdate}
        onEnded={handleTimeEnded}
      ></audio>
    </PlayerBarWrapper>
  )
}

export default memo(AppPlayerBar)
